/******************************************************************************
 * Copyright 2024 zhangcong. All Rights Reserved.
 *****************************************************************************/

#pragma once
#include <stdio.h>
#include <unistd.h>
#include <deque>
#include <list>
#include <vector>
#include <thread>
#include <string>
#include <fstream>
#include <memory>
#include <condition_variable>
#include "common/sensordata.h"
#include "common/common_log.h"
#include "common/common_time_utils.h"
#include "curl/curl.h"
#include "curl/websockets.h"
#include "nlohmann/json.hpp"

using json = nlohmann::json;

struct store_file_info{
    std::string file_dir;
    std::string sensor_name;
    std::string coreCpuid;
    std::string storeCpuID;
    std::string mccaddr;
    std::string sensorchan;
    std::string wsUrl;
    std::string minioEndPoint;
    std::string minioBucketName;
    std::string minioAccessKey;
    std::string minioSecretKey;
    std::string jsonInfo;
    bool upload_file;
    bool upload_data;
};

class StoreFile {
    public:
        StoreFile();
        virtual ~StoreFile();
    
    public:
        int32_t init(const store_file_info &fileinfo);
        void addData(const SensorDataInfo::CommonSensor&data);
        void handleData() ;
        void setUploadFlag(bool flag);
        void uploadFileImmediate();
        void wakeupHistoryUploading();

    protected:
        void saveData(const  SensorDataInfo::CommonSensor& data,bool data_empty);
        void uploadData(const SensorDataInfo::CommonSensor& data);
        void packageData(const SensorDataInfo::CommonSensor& data,  json &packData);
        void saveHead();
        void saveBody(const SensorDataInfo::CommonSensor &data);
        void saveRawDataArray(std::vector<float> rawdataList);

        bool AdduploadFile(const std::string &filename);
        bool uploadFile(const std::string &filename);
        void HandleFileFunc();
        void uploadHistoryFile();
        void saveHistoryFile(const std::string &filename);
        json listToJson( const std::list<std::string> &list);
        std::list<std::string> jsonToList(json objjson);
        void writeJsonFile(const std::string &filename, const json &objjson);
        void readJsonFile(const std::string &filename,  json &objjson);
        int32_t initWebSocket();
        int32_t deInitWebSocket();
    private:
        std::ofstream m_File_;
        std::string m_SensorName_;
        std::deque<SensorDataInfo::CommonSensor> m_DataArray_;
        std::unique_ptr<std::thread> m_HandleDataThread_;
        std::unique_ptr<std::thread> m_HistoryThread_;
        std::unique_ptr<std::thread> m_UploadFileThread_;
        std::condition_variable m_Condition_;
        std::mutex m_Mutex_;
        std::mutex m_HistoryMutex_;
        std::mutex m_FileMutex_;
        std::string m_FileDir_;
        std::string m_LastFileName_;
        bool m_Uploadfile_;
        bool m_UploadHistoryfile_;
        std::list<std::string> m_HistoryFileList_;
        std::list<std::string> m_FileList_;
        json  m_platform_url_;
        CURL *m_upload_curl;
        bool m_uploadData;
        bool m_handleData;
        bool m_handleFile;
        store_file_info m_storeFileInfo;
        int64_t m_lastUpfileTime_;
        int64_t m_lastUpdataTime_;
};
